package dev.ideas.funkyj.sequence;

import dev.ideas.funkyj.function.F3;
import dev.ideas.funkyj.function.P;
import dev.ideas.funkyj.function.P3;
import dev.ideas.funkyj.support.Iterators;
import dev.ideas.funkyj.tuple.Trio;

import java.util.Iterator;

import static dev.ideas.funkyj.sequence.Sequence.from;

/**
 */
public class Sequence3<T1, T2, T3> extends _Sequence<Trio<T1, T2, T3>> {

    protected Sequence3(final Iterable<Trio<T1, T2, T3>> iterable) {
        super(iterable);
    }

    public Sequence3(final Iterable<T1> t1, final Iterable<T2> t2, final Iterable<T3> t3) {
        this(new Iterable<Trio<T1, T2, T3>>() {
            public Iterator<Trio<T1, T2, T3>> iterator() {
                return new Iterators.TrioIterator<T1, T2, T3>(t1.iterator(), t2.iterator(), t3.iterator());
            }
        });
    }

    public Sequence3<T1, T2, T3> where(final P3<T1, T2, T3> p) { return (Sequence3<T1, T2, T3>) super.where(p); }

    public Sequence3<T1, T2, T3> where1(final P<T1> p) {
        return where(new P3<T1, T2, T3>() {
            @Override public boolean apply(T1 t1, T2 t2, T3 t3) {
                return p.apply(t1);
            }
        });
    }
    public Sequence3<T1, T2, T3> where2(final P<T2> p) {
        return where(new P3<T1, T2, T3>() {
            @Override public boolean apply(T1 t1, T2 t2, T3 t3) {
                return p.apply(t2);
            }
        });
    }
    public Sequence3<T1, T2, T3> where3(final P<T3> p) {
        return where(new P3<T1, T2, T3>() {
            @Override public boolean apply(T1 t1, T2 t2, T3 t3) {
                return p.apply(t3);
            }
        });
    }

    //to flat
    public <T> Sequence<T> to(final F3<? super T1, ? super T2, ? super T3, T> f2) {
        return from(this).to(f2);
    }

    public Trio<T1, T2, T3> first() {
        Iterator<Trio<T1, T2, T3>> iterator = iterator(); //re-initiate
        return iterator.hasNext() ? iterator.next() : null;
    }
}